import {
  registerDecorator,
  ValidationOptions,
  ValidatorConstraint,
  ValidatorConstraintInterface,
  ValidationArguments
} from 'class-validator'

/**
 * 强密码验证器
 */
@ValidatorConstraint({ name: 'isStrongPassword', async: false })
export class IsStrongPasswordConstraint implements ValidatorConstraintInterface {
  validate(password: string, args: ValidationArguments) {
    if (!password) return false

    // 至少8位，包含大小写字母、数字和特殊字符
    const strongPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
    return strongPasswordRegex.test(password)
  }

  defaultMessage(args: ValidationArguments) {
    return '密码必须至少8位，包含大小写字母、数字和特殊字符'
  }
}

/**
 * 用户名验证器
 */
@ValidatorConstraint({ name: 'isValidUsername', async: false })
export class IsValidUsernameConstraint implements ValidatorConstraintInterface {
  validate(username: string, args: ValidationArguments) {
    if (!username) return false

    // 用户名只能包含字母、数字、下划线和连字符，长度3-20位
    const usernameRegex = /^[a-zA-Z0-9_-]{3,20}$/
    return usernameRegex.test(username)
  }

  defaultMessage(args: ValidationArguments) {
    return '用户名只能包含字母、数字、下划线和连字符，长度3-20位'
  }
}

/**
 * 强密码装饰器
 */
export function IsStrongPassword(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsStrongPasswordConstraint
    })
  }
}

/**
 * 有效用户名装饰器
 */
export function IsValidUsername(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsValidUsernameConstraint
    })
  }
}

/**
 * 有效Slug验证器
 */
@ValidatorConstraint({ name: 'isValidSlug', async: false })
export class IsValidSlugConstraint implements ValidatorConstraintInterface {
  validate(slug: string, args: ValidationArguments) {
    if (!slug) return false

    // Slug只能包含小写字母、数字和连字符
    const slugRegex = /^[a-z0-9-]+$/
    return slugRegex.test(slug)
  }

  defaultMessage(args: ValidationArguments) {
    return 'Slug只能包含小写字母、数字和连字符'
  }
}

/**
 * 有效颜色验证器
 */
@ValidatorConstraint({ name: 'isValidColor', async: false })
export class IsValidColorConstraint implements ValidatorConstraintInterface {
  validate(color: string, args: ValidationArguments) {
    if (!color) return false

    // 支持十六进制颜色格式
    const colorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
    return colorRegex.test(color)
  }

  defaultMessage(args: ValidationArguments) {
    return '颜色必须是有效的十六进制格式（如 #FF0000）'
  }
}

/**
 * 有效标签验证器
 */
@ValidatorConstraint({ name: 'isValidTags', async: false })
export class IsValidTagsConstraint implements ValidatorConstraintInterface {
  validate(tags: string[], args: ValidationArguments) {
    if (!Array.isArray(tags)) return false

    // 每个标签长度不超过20个字符
    return tags.every(tag => typeof tag === 'string' && tag.length <= 20)
  }

  defaultMessage(args: ValidationArguments) {
    return '每个标签长度不能超过20个字符'
  }
}

/**
 * 有效Slug装饰器
 */
export function IsValidSlug(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsValidSlugConstraint
    })
  }
}

/**
 * 有效颜色装饰器
 */
export function IsValidColor(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsValidColorConstraint
    })
  }
}

/**
 * 有效标签装饰器
 */
export function IsValidTags(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsValidTagsConstraint
    })
  }
}
